package org.feichao.xdao;

import org.feichao.xdao.util.DefaultLogger;

import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * DAO工厂
 *
 * @author chao
 * @version 2015-05-25
 */
public class XDAO {

    /**
     * 调试信息开关
     */
    public static boolean debug = false;

	public static final String DefaultDataSourceName = "default";

	/**
	 * 日志
	 */
	private static Logger log = new DefaultLogger();

    /**
     * 设置日志
     *
     * @param l
     */
    public static void setLog(Logger l){
        log = l;
    }

    /**
     * 获取日志
     *
     * @return
     */
    public static Logger getLog(){
        return log;
    }

	private static Map<String, DataSource> dataSourceMap = new ConcurrentHashMap();

    /**
	 * 设置数据源
	 *
	 * @param ds
	 */
	public static void setDataSource(DataSource ds){
		dataSourceMap.put(DefaultDataSourceName, ds);
	}

	/**
	 * 设置数据源
	 *
	 * @param name
	 * @param ds
	 */
	public static void setDataSource(String name, DataSource ds){
		dataSourceMap.put(name, ds);
	}

    /**
     * 获取数据源
     *
     * @return
     */
    public static DataSource getDataSource(){
		return dataSourceMap.get(DefaultDataSourceName);
    }

	/**
	 * 获取数据源
	 *
	 * @return
	 */
	public static DataSource getDataSource(String name){
		DataSource ds = dataSourceMap.get(name);
		if(ds == null){
			throw new RuntimeException("DataSource["+name+"] not exist");
		}
		return ds;
	}



    /**
     * 获取DAO接口实现
     * @param daoClazz
     * @param <T>
     * @return
     */
	public static <T> T get(Class<T> daoClazz){
		return (T)Proxy.newProxyInstance(daoClazz.getClassLoader(), new Class[]{
				daoClazz
		}, new DAOImplement());
	}

	/**
	 * 获取Dao
	 * @param modelClass
	 * @param <T>
     * @return
     */
	public static <T> Dao<T> getDao(Class<T> modelClass){
		return new Dao(modelClass);
	}

	/**
	 * 数据源接口
	 */
	public static abstract class DataSource{

		/**
		 * 获取数据库连接
		 * @return
		 */
		public abstract Connection getConnection();

		/**
		 * 释放资源
		 * @return
         */
		public boolean close(){return false;}

	}

	/**
	 * 日志接口
	 */
	public static interface Logger{

		void info(String msg);

		void warn(String msg);

		void error(String msg);

		void error(Throwable e, String msg);
	}


}
